package cn.itsource.ymcc.service.impl;

import cn.itsource.ymcc.constants.CommonConstants;
import cn.itsource.ymcc.constants.SmsCodeConstants;
import cn.itsource.ymcc.constants.YmccError;
import cn.itsource.ymcc.domain.MessageSms;
import cn.itsource.ymcc.dto.RedisRegisterDto;
import cn.itsource.ymcc.exception.GlobalException;
import cn.itsource.ymcc.service.IMessageSmsService;
import cn.itsource.ymcc.service.IVerifycodeService;
import cn.itsource.ymcc.util.AssertUtil;
import cn.itsource.ymcc.util.StrUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.concurrent.TimeUnit;
@Service
@Slf4j
public class VerifycodeServiceImpl implements IVerifycodeService {
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;
    @Autowired
    private SmsCodeConstants smsCodeConstants;
    @Autowired
    private IMessageSmsService MessageSmsService;

//    @Override
//    public String ImageCode(String key) {
//        if(!StringUtils.hasLength(key)){
//            throw new GlobalException("滚滚滚");
//        }
//        // 这里是生成code 显示码的个数以及拿到
//        String code = StrUtils.getComplexRandomString(4);
//        // 保存redis，设置过期时间  key是什么==前端请求给我传递的UUID
//        redisTemplate.opsForValue().set(key,code,4, TimeUnit.MINUTES);
//        System.out.println("redisTemplate     :"+redisTemplate.opsForValue().get(key));
//        return VerifyCodeUtils.verifyCode(100,40,code);
//        // 上面是得到图形验证码
//    }

    @Override
    public void smsCode(String mobile) {
//         * 一：校验
//         *  1.空校验
        if(StringUtils.isEmpty(mobile)){
            throw new GlobalException("不能是空的哦");
        }
//         *  2.格式校验   使用303 判断是否是电话格式
        AssertUtil.isPhone(mobile,YmccError.COMMON_PHONE_ILLEGAL.getMessage());//手机号不合法
            //得到key 是经过拼接的key
        String key = String.format(CommonConstants.REGISTER_PHONE_PRIFIX, mobile);
        Date now = new Date();
//         * 二：验证码

//         *  1.校验手机号是否发送过验证码
        Object o = redisTemplate.opsForValue().get(key);
        //有个code后面好用
        String code = null;
        if(o!=null){
            //判断时间是否超时
            RedisRegisterDto registerDto = (RedisRegisterDto) o;
            //判断间隔时间是否超过60s     优化： 一些可变常量的使用需要自动注解来调用
            boolean canSend=now.getTime() - registerDto.getTime() / 1000 >  smsCodeConstants.getInterval();
            System.out.println("889898:"+canSend);
            // 条件正确 ，否则就抛出这个异常
            AssertUtil.isTrue(canSend, YmccError.COMMON_SERIOUS.getMessage());
                //重新发送 重发时间到了， 但是马没有过期，
             code = registerDto.getCode();
        }else {
            //  没有找到 那么就制止走发送
            code = StrUtils.getRandomString(smsCodeConstants.getSize());
        }
            // 存储验证码     拼接验证码
            RedisRegisterDto redisRegisterDto = new RedisRegisterDto(code, now.getTime());
            //存在redis
        redisTemplate.opsForValue().set(key,redisRegisterDto,smsCodeConstants.getTimeout(),TimeUnit.SECONDS);
        //发送短信
//        System.out.println("亲，您的验证码是：" + code + "。请在3分钟内使用！！");
        String message = String.format(smsCodeConstants.getSmsmessage(), code);
        log.info(message);
        //发消息到数据库
        saveMessageSms(now, code, message);


        }

    private void saveMessageSms(Date now, String code, String message) {
        MessageSms messageSms = new MessageSms();
        messageSms.setContent(message);
        messageSms.setSendTime(now);
        messageSms.setTitle(smsCodeConstants.getTitle());
        //获取请求体
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        messageSms.setIp(request.getRemoteAddr());//获取IP地址
        MessageSmsService.insert(messageSms);
    }


//         *  2.从redis拿到了
//         *    2.1 没有过重发时间，使劲骂
//         *    2.2 过了重发时间，使用还未过期的码儿
//         *  3.拿不到
//         * 3.1.生成验证码

//         * 3.2.存储验证码
//         * 3.3.发送验证码短信
//         * 3.4.存储发送信息到数据库
//         * @param mobile
//         */



}
